package com.jjsc.cart.service.impl;

import com.jjsc.cart.api.domain.CartInfo;
import com.jjsc.cart.service.ICartService;
import com.jjsc.common.core.constant.SecurityConstants;
import com.jjsc.common.core.context.SecurityContextHolder;
import com.jjsc.common.core.domain.R;
import com.jjsc.common.core.exception.ServiceException;
import com.jjsc.common.security.utils.SecurityUtils;
import com.jjsc.product.api.RemoteProductService;
import com.jjsc.product.api.domain.ProductSku;
import com.jjsc.product.api.domain.skuPriceVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundGeoOperations;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: 钟城明
 * @CreateTime: 2025-10-30
 * @Description:
 * @Version: 1.0
 */
@Slf4j
@Service
public class CartServiceImpl implements ICartService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RemoteProductService remoteProductService;

    /**
     * 获取用户购物车列表中选中商品列表
     *
     * @param userId 用户ID
     * @return 用户购物车列表中选中商品列表
     */
    @Override
    public List<CartInfo> getCartCheckedList(Long userId) {
        List<CartInfo> cartInfoChecked = new ArrayList<>();
        String catKey = this.getCatKey(userId);
        List<CartInfo> cartInfoList = redisTemplate.opsForHash().values(catKey);
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            cartInfoList.forEach(cartInfo -> {
                if (cartInfo.getIsChecked() == 1) {
                    cartInfoChecked.add(cartInfo);
                }
            });
        }
        return cartInfoChecked;
    }

    @Override
    public void allCheckCart(Integer isChecked) {
        String catKey = this.getCatKey(SecurityContextHolder.getUserId());
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(catKey);
        List<CartInfo> cartInfos = hashOps.values();
        if (!CollectionUtils.isEmpty(cartInfos)) {
            cartInfos.forEach(cartInfo -> {
                cartInfo.setIsChecked(isChecked);
                hashOps.put(cartInfo.getSkuId().toString(), cartInfo);
            });
        }
    }

    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        String catKey = this.getCatKey(SecurityContextHolder.getUserId());
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(catKey);
        CartInfo cartInfo = (CartInfo) redisTemplate.opsForHash().get(catKey, skuId.toString());
        cartInfo.setIsChecked(isChecked);
        redisTemplate.opsForHash().put(catKey, skuId.toString(), cartInfo);
    }

    @Override
    public void deleteCart(Long skuId) {
        String catKey = this.getCatKey(SecurityContextHolder.getUserId());
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(catKey);
        if (hashOps.hasKey(skuId.toString())) {
            hashOps.delete(skuId.toString());
        }
    }

    /**
     * 获取当前用户的购物车列表。
     * 该方法通过获取当前登录用户的 ID 来构建 Redis 中对应的购物车键，
     * 然后从 Redis 的哈希结构中读取所有的购物车信息并返回。
     *
     * @return 当前用户的所有购物车项列表，如果无数据则返回空列表
     */
    @Override
    public List<CartInfo> catList() {
        String catKey = this.getCatKey(SecurityContextHolder.getUserId());
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(catKey);
        List<CartInfo> cartInfos = hashOps.values();
        if (!CollectionUtils.isEmpty(cartInfos)) {
            List<CartInfo> collect = cartInfos
                    .stream()
                    .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))
                    .collect(Collectors.toList());
            return collect;
        }
        return null;
    }


    /**
     * 当前用户加购
     *
     * @param skuId skuId
     * @param num   num
     */
    @Override
    public void addCart(Long skuId, Integer num) {
        //判断购物车中是否有该商品
        Long userId = SecurityUtils.getUserId();
        String catKey = this.getCatKey(userId);
        String field = skuId.toString();
        //如果存在，则更新数量，单品数量上限99
        Boolean exist = redisTemplate.opsForHash().hasKey(catKey, field);
        if (exist) {
            CartInfo cartInfo = (CartInfo) redisTemplate.opsForHash().get(catKey, field);
            Integer skuNum = cartInfo.getSkuNum();
            cartInfo.setSkuNum(skuNum + num > 99 ? 99 : skuNum + num);
            cartInfo.setUpdateTime(new Date());
            redisTemplate.opsForHash().put(catKey, field, cartInfo);
        } else {
            //如果不存在，则构建购物车商品对象，并保存到购物车中
            Long count = redisTemplate.opsForHash().size(catKey);
            if (count > 50) {
                throw new ServiceException("只能加入50个商品");
            }
            R<ProductSku> res = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
            if (res.getCode() != 200) {
                throw new ServiceException("调用商品服务模块失败，原因：" + res.getMsg());
            }
            ProductSku productSku = res.getData();
            CartInfo cartInfo = new CartInfo();
            cartInfo.setUserId(userId);
            cartInfo.setSkuId(productSku.getId());
            cartInfo.setSkuPrice(productSku.getPrice());
            cartInfo.setSkuNum(num > 99 ? 99 : num);
            cartInfo.setThumbImg(productSku.getThumbImg());
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setCreateTime(new Date());
            cartInfo.setIsChecked(1);
            redisTemplate.opsForHash().put(catKey, field, cartInfo);
        }

    }

    @Override
    public Boolean updateCartPrice(Long userId) {
        String catKey = this.getCatKey(userId);
        List<CartInfo> cartInfoList = redisTemplate.opsForHash().values(catKey);
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            for (CartInfo cartInfo : cartInfoList) {
                if (cartInfo.getIsChecked().intValue() == 1) {
                    skuPriceVo skuPrice = remoteProductService.getSkuPrice(cartInfo.getSkuId(),
                            SecurityConstants.INNER).getData();
                    cartInfo.setSkuPrice(skuPrice.getPrice());
                    redisTemplate.opsForHash().put(catKey, cartInfo.getSkuId().toString(), cartInfo);
                }
            }
        }
        return true;
    }

    /**
     * 删除选中商品
     *
     * @param userId
     * @return
     */
    @Override
    public Boolean deleteCartCheckedList(Long userId) {
        String catKey = this.getCatKey(userId);
        List<CartInfo> cartInfoList = redisTemplate.opsForHash().values(catKey);
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            for (CartInfo cartInfo : cartInfoList) {
                if (cartInfo.getIsChecked().intValue() == 1) {
                    redisTemplate.opsForHash().delete(catKey, cartInfo.getSkuId().toString());
                }
            }
        }
        return true;
    }

    private String getCatKey(Long userId) {
        return "user:cart:" + userId;
    }
}
